#pragma once

// #include <odb/database.hxx>
// #include <odb/mysql/database.hxx>
// #include <sstream>
#include "create_mysql_client.hpp"
#include "user.hxx"
#include "user-odb.hxx"
#include "logger.hpp"

namespace xu
{
    class ManageUser
    {
    public:
        using ptr = std::shared_ptr<ManageUser>;
        ManageUser(std::shared_ptr<odb::mysql::database> db)
        :_db(db)
        {}

        //插入数据
        bool Insert(User & user)
        {
            try 
            {
                //获取事务对象开启事务
                odb::transaction trans(_db->begin());
                _db->persist(user);
                //提交事务
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("插入用户数据出错： {}", e.what() );
                return false;
            }
            LOG_INFO("插入用户数据成功");
            return true;
        }
        //修改数据
        bool Update(const User & user)
        {
           try 
            {
                //获取事务对象开启事务
                odb::transaction trans(_db->begin());
                _db->update(user);
                //提交事务
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("更新用户数据出错： {}", e.what() );
                return false;
            }
            LOG_INFO("更新用户数据成功");
            return true; 
        }

        void Delete(User & user)
        {
            try 
            {
                // 开始事务
                odb::transaction t(_db->begin());
                _db->erase<User>(user);
                // 提交事务
                t.commit();

            } 
            catch (const odb::exception& e) 
            {
                LOG_ERROR("删除用户数据出错： {}", e.what() );
                return ;
            }

            LOG_INFO("删除用户数据成功");
        }

        //通过用户id查询
        std::shared_ptr<User> SelectUserId(const std::string  & user_id)
        {
            std::shared_ptr<User> res;
            try 
            {
                //获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                res.reset(_db->query_one<User>(query::user_id == user_id));
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("通过用户id查找出错： {}", e.what() );
                return std::shared_ptr<User>();
            }
            LOG_INFO("通过用户id查找成功");
            return res;
        }
        //通过手机号码查询
        std::shared_ptr<User> SelectPhoneNumber(const std::string  & phone_number)
        { 
            std::shared_ptr<User> res;
            try 
            {
                //获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                res.reset(_db->query_one<User>(query::phone_number == phone_number));
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("通过用户手机号码查找出错： {}", e.what() );
                return std::shared_ptr<User>();
            }
            LOG_INFO("通过用户手机号码查找成功");
            return res;
        }
        //通过昵称查询
       std::shared_ptr<User> SelectNickName(const std::string  & nickname)
        {
            std::shared_ptr<User> res;
            try 
            {
                //获取事务对象开启事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                res.reset(_db->query_one<User>(query::nickname == nickname));
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("通过用户昵称查找出错： {}", e.what() );
                return std::shared_ptr<User>();
            }
            LOG_INFO("通过用户昵称查找成功");
            return res;
        }
        //批量用户id查询
        std::vector<User> SelectListUserId(const std::vector<std::string> & user_ids)
        {
            if(user_ids.empty())
            {
                return std::vector<User>();
            }
            std::vector<User> res;
            try 
            {
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                typedef odb::result<User> result;
                std::stringstream ss;
                ss << "user_id in (";
                for (const auto &id : user_ids) {
                    ss << "'" << id << "',";
                }
                std::string condition = ss.str();
                condition.pop_back();
                condition += ")";
                result r(_db->query<User>(condition));
                for (result::iterator i(r.begin()); i != r.end(); ++i) {
                    res.push_back(*i);
                }
                trans.commit();
            }
            catch (std::exception &e) 
            {
                LOG_ERROR("通过用户ID批量查询用户失败:{}！", e.what());
                return std::vector<User>();
            }
            LOG_INFO("通过用户ID批量查询成功");
            return res;
        }
        
    private:
        std::shared_ptr<odb::mysql::database> _db;
    };
}
